/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation
**
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
**     the names of its contributors may be used to endorse or promote
**     products derived from this software without specific prior written
**     permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/

#include <supservices_symbian.h>
#include <etel3rdparty.h>
#include <supservices.h>

/*!
 * Symbian static constructor.
 */
SupServicesPrivate* SupServicesPrivate::NewL(SupServices *aPublicInterface)
{
    SupServicesPrivate* self = new (ELeave) SupServicesPrivate(aPublicInterface);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
}

/*!
 * Symbian second stage constructor.
 */
void SupServicesPrivate::ConstructL()
{
    iTelephony = CTelephony::NewL();
}

// Private constructor - initialise the pointer to the public API class
// and make this standard priority for scheduling.
SupServicesPrivate::SupServicesPrivate(SupServices *aPublicInterface)
    : iPublic(aPublicInterface), CActive(CActive::EPriorityStandard),
      iCallBarringSupplServicesV1Pckg(iCallBarringSupplServicesV1),
      iCallForwardingSupplServicesV1Pckg(iCallForwardingSupplServicesV1),
      iCallWaitingSupplServicesV1Pckg(iCallWaitingSupplServicesV1),
      iTIdentityServiceV1Pckg(iTIdentityServiceV1)
{
    // Adding this Active object
    // to an Active scheduler.
    CActiveScheduler::Add(this);
}

/*!
 * Destructor.
 */
SupServicesPrivate::~SupServicesPrivate()
{
    // Cancel any outstanding async request before this object is destroyed
    // in order to avoid stray signals.
    // This destructor cannot leave.
    Cancel(); //  Calls DoCancel()
    if( iTelephony )
    {
        delete iTelephony;
        iTelephony = NULL;
    }

}

/*!
 * Obtains status for the call barring supplementary service.
 */

void SupServicesPrivate::GetCallBarringStatus()
{

    CTelephony::TCallBarringCondition condition = CTelephony::EBarAllOutgoing;

    // Obtains the call barring status for "Outgoing Calls".
    // Depending upon the phone settings, the call barring status could be active,
    // inactive or not avilable. The status can also be not provisioned on GSM/WCDMA networks.

    iTelephony->GetCallBarringStatus(iStatus, condition, iCallBarringSupplServicesV1Pckg);
    iSupServiceType = ECallBarred;
    SetActive();

}

/*!
 * Obtains status for the call forwarding supplementary service.
 */
void SupServicesPrivate::GetCallForwardingStatus()
{
    CTelephony::TCallForwardingCondition condition = CTelephony::ECallForwardingNoReply;

    // Obtains the call forwarding status on "No Reply".
    // Depending upon the phone settings, the call forwarding status could be active,
    // inactive, not avilable or not provisioned.

    iTelephony->GetCallForwardingStatus(iStatus, condition, iCallForwardingSupplServicesV1Pckg);
    iSupServiceType = ECallForwarded;
    SetActive();

}

/*!
 * Obtains status for the call waiting supplementary service.
 */
void SupServicesPrivate::GetCallWaitingStatus()
{
    // Obtains the call waiting status .
    // Depending upon the phone settings, the call waiting status could be active,
    // inactive or not avilable. The status can also be not provisioned on GSM/WCDMA networks.

    iTelephony->GetCallWaitingStatus(iStatus, iCallWaitingSupplServicesV1Pckg);
    iSupServiceType = ECallWaiting;
    SetActive();
}

/*!
 * Obtains the caller identification service status information.
 */
void SupServicesPrivate::GetCallerIdentityStatus()
{
    CTelephony::TIdentityService condition = CTelephony::EIdServiceCallerPresentation;

    // Obtains the status for Calling Line Identification Presentation. This condition
    // enables the phone to display the number of remote party that calls your phone.
    // The status information can be active, restricted, allowed, not provisioned or unknown,
    // depending upon the phone settings.

    iTelephony->GetIdentityServiceStatus(iStatus, condition, iTIdentityServiceV1Pckg);
    iSupServiceType = ECallerIdentification;
    SetActive();
}

/*!
 * This method is invoked to handle a request completion event.
 * It obtains the supplementary service status for a given condition.
 */
void SupServicesPrivate::RunL()
{
    if( iStatus == KErrNone )
    {
        switch( iSupServiceType )
        {
        case ECallBarred:
            {
                if( iCallBarringSupplServicesV1.iCallBarringCondition == CTelephony::EBarAllOutgoing)
                {
                    _LIT(KCallBarMessage,"Bar Outgoing calls");
                    // Buffer for outgoing call bar status information.
                    TBuf<64> message(KCallBarMessage);

                    // Appends the call bar status to the buffer.
                    message.Append(GetSupServiceStatus(iCallBarringSupplServicesV1.iCallBarring));
                    iPublic->getMessage(message);
                }
                else
                {
                    _LIT(KNoCallBarMessage,"Outgoing calls not barred");

                    // Buffer providing information that outgoing calls are not barred.
                    TBuf<64> message(KNoCallBarMessage);
                    iPublic->getMessage(message);
                }
                break;
            }

        case ECallForwarded:
            {
                if( iCallForwardingSupplServicesV1.iCallForwardingCondition == CTelephony::ECallForwardingNoReply )
                {
                    _LIT(KCallForwardMessage,"Call forward on noReply");
                    // Buffer for call forward status information
                    TBuf<64> message(KCallForwardMessage);

                    // Appends the call forward status to the buffer .
                    message.Append(GetSupServiceStatus(iCallForwardingSupplServicesV1.iCallForwarding));
                    iPublic->getMessage(message);
                }

                else
                {
                    _LIT(KNoCallForwardMessage,"Call forward on noReply not set");
                    // Buffer providing information that call forwarding on no reply is not set.
                    TBuf<64> message(KNoCallForwardMessage);
                    iPublic->getMessage(message);
                }
                break;
            }

        case ECallWaiting:
            {
            _LIT(KCallWaitMessage,"Call waiting");
            // Buffer to hold the call waiting status information.
            TBuf<64> message(KCallWaitMessage);

            // Appends the call waiting status returned to the buffer.
            message.Append(GetSupServiceStatus(iCallWaitingSupplServicesV1.iCallWaiting));
            iPublic->getMessage(message);
            break;
            }

        case ECallerIdentification:
            {
            // Buffer holding the CLIP status information.
            TBuf<64> message;
            // Returns the "Calling Line Identification Presentation" status.
            switch(iTIdentityServiceV1.iIdentityStatus)
            {
            case CTelephony::EIdServiceActivePermanent:
                {
                _LIT(KCLIPActiveMessage,"CLIP is permanently active");
                message.Append(KCLIPActiveMessage);
                break;
                }
            case CTelephony::EIdServiceActiveDefaultRestricted:
                {
                _LIT(KCLIPRestrictedMessage,"CLIP is restricted");
                message.Append(KCLIPRestrictedMessage);
                break;
                }
            case CTelephony::EIdServiceActiveDefaultAllowed:
                {
                _LIT(KCLIPAllowedMessage,"CLIP is Allowed");
                message.Append(KCLIPAllowedMessage);
                break;
                }
            case CTelephony::EIdServiceNotProvisioned:
                {
                _LIT(KCLIPNotProvisionedMessage,"CLIP is NotProvisioned");
                message.Append(KCLIPNotProvisionedMessage);
                break;
                }
            case CTelephony::EIdServiceUnknown:
            default:
                {
                _LIT(KCLIPUnknownMessage,"CLIP service is Unknown");
                message.Append(KCLIPUnknownMessage);
                break;
                }

            }
            iPublic->getMessage(message);
            break;
        }

        default:
            break;
        }

    }

    // emits a signal to print the supplementary service status.
    emit iPublic->printMessage();
}

/*!
 * Returns the status of supplementary servives. The status indicates,
 * whether a particular supplementary service is active, inactive, not
 * provisioned, unavailable or unknown.
 */
TDes& SupServicesPrivate::GetSupServiceStatus(CTelephony::TSupplServiceStatus aStatus)
{
    imessage.Delete(0,imessage.Length());
    switch( aStatus )
    {
    case CTelephony::EStatusActive:
            _LIT(KActiveMessage," active.");
            imessage.Append(KActiveMessage);
            break;
    case CTelephony::ENotActive:
            _LIT(KNotActiveMessage," not active.");
            imessage.Append(KNotActiveMessage);
            break;
    case CTelephony::ENotProvisioned:
            _LIT(KNotProvisionedMessage," not provisioned.");
            imessage.Append(KNotProvisionedMessage);
            break;
    case CTelephony::ENotAvailable:
            _LIT(KNotAvailableMessage," not available.");
            imessage.Append(KNotAvailableMessage);
            break;
    case CTelephony::EUnknown:
    default:
            _LIT(KUnknownMessage," unknown.");
            imessage.Append(KUnknownMessage);
            break;
    }
    return imessage;

}

/*!
 * Cancels any outstanding request.
 */
void SupServicesPrivate::DoCancel()
{
    // Cancels the call barring status request.
    iTelephony->CancelAsync(CTelephony::EGetCallBarringStatusCancel);

    // Cancels the call forwarding status request.
    iTelephony->CancelAsync(CTelephony::EGetCallForwardingStatusCancel);

    // Cancels the call waiting status request.
    iTelephony->CancelAsync(CTelephony::EGetCallWaitingStatusCancel);

    // Cancels the Identity service status request.
    iTelephony->CancelAsync(CTelephony::EGetIdentityServiceStatusCancel);

}

